Processing Data from the NCAR Mesa Lab Weather Station

There is a weather station located at the Mesa Lab, situated along the Foothills of the Rockies in Boulder, Colorado!

By the end of this post, you will be able to plot an interactive visualization of the weather data collected at the Mesa Lab, as shown below!

mesa_lab_gif

Here is a picture of the lab and one of the weather stations!

ncar-mesa-lab

image.png

The Data

This station collects data every 10 minutes, is publicly available from this site, with live plots viewable here

For this example, we downloaded a weeks’s worth of daily data from this past week. You can access the FTP server using this this link, pulling data from the /mesa directory.

Imports

In this example, we utilize xarray and pandas for data cleaning, and hvplot/holoviews for visualization!

import holoviews as hv
import hvplot
import hvplot.xarray
import pandas as pd
import xarray as xr
from metpy.units import units

hv.extension('bokeh')

Reading in the Data

We can wrap this into a function, then pass this into xr.open_mfdataset to process multiple files at the same time!

ds = xr.open_mfdataset('data/mlab*', engine='netcdf4', concat_dim='time').load()
ds
<xarray.Dataset>
Dimensions:      (time: 4043)
Coordinates:
  * time         (time) datetime64[ns] 2021-11-01 ... 2021-11-15
Data variables: (12/17)
    lat          (time) float64 39.98 39.98 39.98 39.98 ... 39.98 39.98 39.98
    lon          (time) float64 -105.3 -105.3 -105.3 ... -105.3 -105.3 -105.3
    alt          (time) float64 1.885e+03 1.885e+03 ... 1.885e+03 1.885e+03
    pres         (time) float64 813.3 813.4 813.4 813.5 ... 811.0 810.9 810.8
    rain_accum   (time) float64 408.9 408.9 408.9 408.9 ... 410.8 410.8 410.8
    rh           (time) float64 75.6 75.3 75.3 75.5 75.6 ... 26.2 26.5 26.6 26.5
    ...           ...
    V            (time) float64 -2.252 -1.386 -2.035 ... -5.129 -2.666 -4.623
    dewpoint     (time) float64 -2.139 -2.096 -2.193 ... -3.314 -3.349 -3.314
    cpres0       (time) float64 1.022e+03 1.022e+03 ... 1.019e+03 1.019e+03
    windchill    (time) float64 -0.5018 1.8 0.1822 -1.764 ... 6.599 7.137 6.091
    raina_event  (time) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0
    raina_daily  (time) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0
Attributes:
    site_name:      NCAR Mesa Lab
    site_location:  NCAR Mesa Lab, South West Boulder, CO
    Conventions:    CF-1.7

We can plot a basic plot using the .plot() method in xarray

ds.tdry.plot();
_images/Mesa-Lab-Weather-Station-Demo_7_0.png

Plotting an Interactive Meteogram

We can also plot a “meteogram” which is a collection of different surface observations.

We know from the .nc files that variables have the following units:

  • Temperature (tdry) - degrees Celsius

  • Dewpoint (dewpoint) - degrees Celsius

  • Wind (wspd)- meter/second

  • Max Wind Speed (wspd_max) - meter/second

We start by defining our plots, as shown below:

Converting to Standard Units

We can use metpy.units here to convert to standard units!

ds_standard_units = ds.copy()

# Convert windspeed
ds_standard_units['wspd'] = ('time', (ds.wspd.values * units('m/s')).to('mph'))
ds_standard_units.wspd.attrs['units'] = 'mph'

# Convert max windspeed
ds_standard_units['wspd_max'] = ('time', (ds.wspd_max.values * units('m/s')).to('mph'))
ds_standard_units.wspd_max.attrs['units'] = 'mph'

# Convert windspeed
ds_standard_units['tdry'] = ('time', (ds.tdry.values * units('degC')).to('degF'))
ds_standard_units.tdry.attrs['units'] = 'degF'

# Convert max windspeed
ds_standard_units['dewpoint'] = ('time', (ds.dewpoint.values * units('degC')).to('degF'))
ds_standard_units.dewpoint.attrs['units'] = 'degF'

Setup our Wind Plots

We now can setup our plots - starting with wind speed. We add a few labels, and merge them within the same subplot using the * syntax in holoviews!

wind_speed_plot = ds_standard_units.wspd.hvplot.line(
    ylabel='Wind Speed (mph)', color='darkblue', label='Wind Speed'
)
wind_speed_max_plot = ds_standard_units.wspd_max.hvplot.scatter(
    color='lightblue', label='Peak Wind Speed'
)
wind_speed_max_plot * wind_speed_plot

Setup our Temperature Plots

We follow the same process for our temperature/dewpoint plots, adding an alpha argument to lighten the colors a bit.

temperature_plot = ds_standard_units.tdry.hvplot.line(
    ylabel='Temperature (degF)', color='red', label='Temperature', alpha=0.4
)
dewpoint_plot = ds_standard_units.dewpoint.hvplot.line(color='green', label='Dewpoint', alpha=0.4)
temperature_plot * dewpoint_plot

Bringing it All Together

Now that our plots are all setup, we can merge them into the same figure using the following syntax, specifying a single column and a legend located in the top left of each subplot:

hv.Layout(
    (wind_speed_max_plot * wind_speed_plot).opts(legend_position='top_left')
    + (temperature_plot * dewpoint_plot).opts(legend_position='top_left')
).cols(1)